package config

import (
	"database/sql"
	"fmt"
	"os"
	"strconv"

	"github.com/aliyun/alibaba-cloud-sdk-go/services/sts"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	_ "github.com/go-sql-driver/mysql"
	"github.com/joho/godotenv"
)

// 全局实例
var (
	DB               *sql.DB       // 数据库连接池实例
	Aliyun           *AliyunConfig // 阿里云配置实例
	WPS              *WPSConfig    // 金山登录配置实例
	DBConfigInstance *DBConfig     // 数据库配置实例
)

// 配置结构体
// DBConfig 数据库配置
type DBConfig struct {
	User     string
	Password string
	Host     string
	Port     string
	Name     string
}

// WPSConfig 金山登录配置
type WPSConfig struct {
	AccessID  string // 金山开发者AccessID
	SecretKey string // 金山开发者SecretKey
	ProxyAddr string // 代理地址
}

// AliyunConfig 阿里云配置结构体
type AliyunConfig struct {
	AccessKeyID     string
	AccessKeySecret string
	Region          string
	Endpoint        string
	Bucket          string
	STSRoleARN      string
	Timeout         int
	TIMEEXPIRES     int
}

var (
	ServerPort     string
	JWTSecret      string
	JWTExpiration  int
	MaxUploadSize  int64
	AllowFileTypes []string
)

// 初始化入口
// Init 初始化配置（加载.env、阿里云、金山配置）
func InitConfig() error {
	// 加载.env文件
	if err := godotenv.Load(".env"); err != nil {
		// 生产环境可能通过系统环境变量注入，非致命错误
		fmt.Printf("警告：加载.env文件失败（忽略此警告如果使用系统环境变量）: %v\n", err)
	}

	// 初始化基础配置
	initBaseConfig()

	// 初始化第三方服务配置
	if err := initThirdPartyConfigs(); err != nil {
		return fmt.Errorf("第三方服务配置初始化失败: %w", err)
	}

	return nil
}

// 基础配置初始化
func initBaseConfig() {
	// 服务器基础配置
	ServerPort = getEnv("SERVER_PORT", "8080")
	JWTSecret = getEnv("JWT_SECRET", "default-insecure-secret") // 生产环境必须修改
	JWTExpiration = getEnvInt("JWT_EXPIRATION", 168)            // JWT有效期（小时）

	// 上传配置
	MaxUploadSize = getEnvInt64("MAX_UPLOAD_SIZE", 10*1024*1024) // 默认10MB
	AllowFileTypes = []string{"image/jpeg", "image/png", "image/gif", "image/webp"}
}

// 第三方服务配置
func initThirdPartyConfigs() error {
	// 初始化阿里云配置
	Aliyun = &AliyunConfig{}
	if err := initAliyun(); err != nil {
		return fmt.Errorf("阿里云配置: %w", err)
	}

	// 初始化金山登录配置
	WPS = &WPSConfig{}
	if err := initWPS(); err != nil {
		return fmt.Errorf("金山登录配置: %w", err)
	}

	// 初始化数据库配置
	DBConfigInstance = &DBConfig{
		User:     getEnv("DB_USER", "root"),
		Password: getEnv("DB_PASSWORD", "748932"),
		Host:     getEnv("DB_HOST", "localhost"),
		Port:     getEnv("DB_PORT", "3306"),
		Name:     getEnv("DB_NAME", "yzh_image_server"),
	}

	return nil
}

// 金山登录配置
func initWPS() error {
	WPS.AccessID = getEnv("WPS_ACCESS_ID", "")
	WPS.SecretKey = getEnv("WPS_SECRET_KEY", "")
	WPS.ProxyAddr = getEnv("WPS_PROXY_ADDR", "http://127.0.0.1:8899") // 默认代理地址

	// 验证核心配置
	if WPS.AccessID == "" || WPS.SecretKey == "" {
		return fmt.Errorf("请在.env中配置WPS_ACCESS_ID和WPS_SECRET_KEY")
	}

	return nil
}

// 阿里云配置
func initAliyun() error {
	Aliyun.AccessKeyID = getEnv("OSS_ACCESS_KEY", "")
	Aliyun.AccessKeySecret = getEnv("OSS_SECRET", "")
	Aliyun.Region = getEnv("OSS_REGION", "cn-wuhan-lr")
	Aliyun.Bucket = getEnv("OSS_BUCKET", "")
	Aliyun.STSRoleARN = getEnv("OSS_STS_ROLE_ARN", "")
	Aliyun.Timeout = getEnvInt("OSS_TIMEOUT", 30)
	Aliyun.TIMEEXPIRES = getEnvInt("OSS_TIME_EXPIRES", 3600)

	// 自动生成Endpoint
	if Aliyun.Endpoint = getEnv("OSS_ENDPOINT", ""); Aliyun.Endpoint == "" {
		Aliyun.Endpoint = fmt.Sprintf("oss-%s.aliyuncs.com", Aliyun.Region)
	}

	// 验证核心配置
	if Aliyun.AccessKeyID == "" || Aliyun.AccessKeySecret == "" {
		return fmt.Errorf("请在.env中配置OSS_ACCESS_KEY和OSS_SECRET")
	}
	if Aliyun.Bucket == "" {
		return fmt.Errorf("请在.env中配置OSS_BUCKET")
	}

	return nil
}

// OSS方法
func NewOSSClient() (*oss.Client, error) {
	return oss.New(
		Aliyun.Endpoint,
		Aliyun.AccessKeyID,
		Aliyun.AccessKeySecret,
	)
}

func NewSTSClient() (*sts.Client, error) {
	return sts.NewClientWithAccessKey(Aliyun.Region, Aliyun.AccessKeyID, Aliyun.AccessKeySecret)
}

// 环境变量函数
func getEnv(key, defaultValue string) string {
	if value, exists := os.LookupEnv(key); exists && value != "" {
		return value
	}
	return defaultValue
}

// 获取环境变量Int类型
func getEnvInt(key string, defaultValue int) int {
	valueStr := getEnv(key, "")
	if valueStr == "" {
		return defaultValue
	}
	value, err := strconv.Atoi(valueStr)
	if err != nil {
		fmt.Printf("警告：环境变量%s转换为int失败，使用默认值%d: %v\n", key, defaultValue, err)
		return defaultValue
	}
	return value
}

// 获取环境变量Int64类型
func getEnvInt64(key string, defaultValue int64) int64 {
	valueStr := getEnv(key, "")
	if valueStr == "" {
		return defaultValue
	}
	value, err := strconv.ParseInt(valueStr, 10, 64)
	if err != nil {
		fmt.Printf("警告：环境变量%s转换为int64失败，使用默认值%d: %v\n", key, defaultValue, err)
		return defaultValue
	}
	return value
}
